package persistencia;

import gamebook.Foto;
import gamebook.UsuarioGenerico;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class PFoto {

    /**
     * Introduce una nueva foto en la base de datos. El valor devuelto indica 
     * el éxito de la operación.
     * @param Foto foto que queremos guardar
     * @return true o false dependiendo de si se guardó bien o no
     */
    public static boolean darAltaBD(Foto foto) {
        boolean resultado = true;         //Si resultado es false es que hubo algún problema
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        //Para el uso de fechas
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            //Conexión con la base de datos
            connection = Persistencia_Conexion.getConnection();
            statement = connection.createStatement();

            //El campo de fecha de nacimiento necesita un tratamiento previo para pasarlo a String
            Date dateFecha = foto.getFecha();
            String stringFecha = dateFormat.format(dateFecha);

            //Valor de EsPerfil debe ser 1 o 0 en la base de datos
            int intEsPerfil = foto.isEsPerfil() ? 1 : 0;
            
            //Valor de EsPublicacion debe ser 1 o 0 en la base de datos
            int intEsPublicacion = foto.isEsPublicacion() ? 1 : 0;

            //Pasamos el INSERT a la base de datos

            String query = "insert into fotos ("
                    + "alto,"
                    + "ancho,"
                    + "descripcion,"
                    + "esPerfil,"
                    + "fecha,"
                    + "id_usuario,"
                    + "esPublicacion) values ("
                    + foto.getAlto() + ","
                    + foto.getAncho() + ","
                    + "'" + foto.getDescripcion() + "',"
                    + intEsPerfil + ","
                    + "'" + stringFecha + "',"
                    + foto.getUsuario().getId() + ", "
                    + intEsPublicacion+")";

            int registros = statement.executeUpdate(query);

            //Verificamos que se haya actualizado UN registro
            if (registros == 1) {
                //Si hemos introducido la nueva foto, le asignamos el ID con el que se guardó en la base de datos
                resultSet = statement.executeQuery("select id from fotos order by id desc");
                if (resultSet.next()) {
                    foto.setId(resultSet.getInt("id"));
                }
            } else {
                //Si no se ha introducido la nueva foto por alguna causa, asignamos false a resultado
                resultado = false;
            }
        } catch (Exception ex) {
            resultado = false;
        } finally {
            //Cerramos todo y salimos
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (Exception ex) {
            }
        }

        return resultado;
    }

    /**
     * Actualiza los datos de una foto en la base de datos. El valor devuelto
     * indica el éxito de la operación, pero esto puede ser por un error o porque
     * los datos que hemos intentado actualizar son iguales a los que había.
     * @param Foto foto que queremos actualizar
     * @return true o false dependiendo de si se cambio algo o no
     */
    public static boolean actualizarBD(Foto foto) {
        boolean resultado = true;         //Si resultado es false es que hubo algún problema
        Connection connection = null;
        Statement statement = null;

        //Para el uso de fechas
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");

        try {
            //Conexión con la base de datos
            connection = Persistencia_Conexion.getConnection();
            statement = connection.createStatement();

            //El campo de fecha necesita un tratamiento previo para pasarlo a String
            Date dateFecha = foto.getFecha();
            String stringFecha = dateFormat.format(dateFecha);

            //Valor de EsPerfil debe ser 1 o 0 en la base de datos
            int intEsPerfil = foto.isEsPerfil() ? 1 : 0;

            //Valor de EsPublicacion debe ser 1 o 0 en la base de datos
            int intEsPublicacion = foto.isEsPublicacion() ? 1 : 0;
            
            //Pasamos el UPDATE a la base de datos
            int registros = statement.executeUpdate("update fotos set "
                    + "alto=" + foto.getAlto() + ","
                    + "ancho=" + foto.getAncho() + ","
                    + "descripcion='" + foto.getDescripcion() + "',"
                    + "esPerfil=" + intEsPerfil + ","
                    + "fecha='" + stringFecha + "',"
                    + "id_usuario=" + foto.getUsuario().getId() + ","
                    + "esPublicacion=" + intEsPublicacion + ","
                    + "where id=" + foto.getId());

            //Verificamos que se haya actualizado UN registro
            if (registros != 1) {
                //Esto puede ser por algún fallo, o porque los valores introducidos son iguales a los que había
                resultado = false;
            }

        } catch (Exception ex) {
            //Si hubo error en algun sitio, ponemos resultado a false
            resultado = false;
        } finally {
            //Cerramos todo y salimos
            try {
                statement.close();
                connection.close();
            } catch (Exception ex) {
            }
        }

        return resultado;
    }

    /**
     * Elimina una imagen de la base de datos
     * @param int id de la imagen que se desea borrar
     * @return true o false dependiendo de si se consiguio eliminar o no la foto
     */
    public static boolean borrarBD(Foto foto){
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        //El valor que vamos a devolver
        boolean resultado;
        //Número de registros que se eliminarán
        int total = 0;

        try {
            //Conexión con la base de datos
            connection = Persistencia_Conexion.getConnection();
            statement = connection.createStatement();

            //Pasamos el SELECT COUNT a la base de datos
            total=statement.executeUpdate("delete from fotos where id=" + foto.getId());

            //Cogemos el número de registros eliminados para ver si se borró
            if (total>0) {
                resultado=true;
            } else {
                resultado=false;
            }

        } catch (Exception ex) {
            resultado=false;
        } finally {
            //Cerramos todo y salimos
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (Exception ex) {
            }
        }

        //Devolvemos el número total de registros encontrados (-1 si hubo fallo)
        return resultado;
    }
    
    /**
     * Devuelve la foto que tiene como id el parámetro que le pasamos
     * al método. Si no existiese dicha foto, la respuesta es un null.
     * @param id id de la foto
     * @return Foto Devuelve una foto o null si no existe foto con dicho id.
     */
    public static Foto seleccionarPorIdBD(int id) {
        List<Foto> listFoto = new ArrayList();
        String sql = "select id, alto, ancho, descripcion, esPerfil, fecha, id_usuario, esPublicacion from fotos where id=" + id;
        listFoto = seleccionarBD(sql, null);
        if (listFoto.isEmpty()) {
            return null;
        } else {
            return listFoto.get(0);
        }
    }

    /**
     * Devuelve el número de fotos de cierto usuario.
     * @param Usuario el usuario que es el dueño de las fotos
     * @return int Número de fotos si hubo algún error devuelve -1
     */
    public static int contarAlbumPorUsuarioBD(UsuarioGenerico usuarioGenerico) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        //El valor que vamos a devolver
        int total = 0;

        try {
            //Conexión con la base de datos
            connection = Persistencia_Conexion.getConnection();
            statement = connection.createStatement();

            //Pasamos el SELECT COUNT a la base de datos
            resultSet = statement.executeQuery("select count(id) total from fotos where id_usuario=" + usuarioGenerico.getId() + " and esPublicacion=0");

            //Cogemos del resultSet el valor de la cuenta
            if (resultSet.next()) {
                total = resultSet.getInt("total");
            } else {
                total = 0;
            }

        } catch (Exception ex) {
            //Si hubo error en algun sitio, devolveremos un -1
            total = -1;
        } finally {
            //Cerramos todo y salimos
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (Exception ex) {
            }
        }

        //Devolvemos el número total de registros encontrados (-1 si hubo fallo)
        return total;
    }

    /**
     * Devuelve una lista de fotos de cierto usuario que le pasamos
     * al método. Si no hubiese ninguno devolvería null.
     * @param Usuario el usuario dueño de las fotos
     * @return List<Foto>
     */
    public static List<Foto> seleccionarAlbumPorUsuarioBD(UsuarioGenerico usuarioGenerico, int inicio, int cantidad) {
        List<Foto> listFoto = new ArrayList();
        String sql = "select id, alto, ancho, descripcion, esPerfil, fecha, id_usuario, esPublicacion from fotos where id_usuario=" + usuarioGenerico.getId() + " and esPublicacion=0 order by fecha desc limit " + inicio + " , " + cantidad;
        listFoto = seleccionarBD(sql, usuarioGenerico);
        return listFoto;
    }

    /**
     * Obtiene una lista de fotos según la consulta sql que pasemos.
     * El parámetro del usuario es opcional. En el caso de que se sepa
     * cuál es el usuario dueño de la imagen puede indicarse y no se solicitará
     * la construcción de dicho usuario. En caso de que no se conozca el usuario
     * se debe pasar el valor null.
     * @param String sql es la consulta que devolverá una lista de fotos
     * @param UsuarioGenerico usuarioGenerico puede ser null si no se conoce o el dueño de la foto si sí se conoce.
     * @return List<Foto>
     */
    public static List<Foto> seleccionarBD(String sql, UsuarioGenerico usuarioGenerico) {
        //Lista de Fotos que devolveremos
        List<Foto> listFoto = new ArrayList();

        //Para conectar con la base de datos
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        //Para usar la fecha
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            //Conectamos con la base de datos
            connection = Persistencia_Conexion.getConnection();
            statement = connection.createStatement();

            //Hacemos la consulta que obtenemos como parámetro
            resultSet = statement.executeQuery(sql);

            //Mientras haya mensajes que cumplan el criterio SQL los vamos añadiendo
            while (resultSet.next()) {
                //Creamos una nueva foto y le ponemos los datos
                Foto foto = new Foto();

                //Metemos todos los datos de la foto
                foto.setId(resultSet.getInt("id"));
                foto.setAlto(resultSet.getInt("alto"));
                foto.setAncho(resultSet.getInt("ancho"));
                foto.setDescripcion(resultSet.getString("descripcion"));
                //Para 'esPerfil' debemos cambiar (1/0) por (true/false)
                if (resultSet.getInt("esPerfil") == 1) {
                    foto.setEsPerfil(true);
                } else {
                    foto.setEsPerfil(false);
                }
                //Para 'esPublicacion' debemos cambiar (1/0) por (true/false)
                if (resultSet.getInt("esPublicacion") == 1) {
                    foto.setEsPublicacion(true);
                } else {
                    foto.setEsPublicacion(false);
                }
                foto.setFecha(dateFormat.parse(resultSet.getString("fecha")));
                if (usuarioGenerico == null) {
                    foto.setUsuario(PUsuarioGenerico.seleccionarPorIdBD(resultSet.getInt("id_usuario")));
                } else {
                    foto.setUsuario(usuarioGenerico);
                }

                //Agregamos a la lista y cogemos la siguiente si la hay
                listFoto.add(foto);
            }

        } catch (Exception ex) {
            System.out.println(ex.toString());
        } finally {
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (Exception ex) {
                System.out.println(ex.toString());
            }
        }

        return listFoto;
    }
}
